package com.richard.library.basic.task;

import java.util.concurrent.TimeUnit;

/**
 * @author: Richard
 * @createDate: 2024/1/30 15:47
 * @version: 1.0
 * @description: 任务信息
 */
public class Task {

    /**
     * 任务执行事件体
     */
    private Runnable event;

    /**
     * 首次执行的延迟时间
     */
    private Long initialDelay;

    /**
     * 连续执行之间的间隔时间
     */
    private Long period;

    /**
     * 延迟时间和连续执行间隔时间的单位
     */
    private TimeUnit timeUnit = TimeUnit.SECONDS;

    /**
     * 任务标识
     */
    private String tag;


    public Task(long initialDelay, long period, TimeUnit timeUnit, Runnable event) {
        this.event = event;
        this.initialDelay = initialDelay;
        this.period = period;
        this.timeUnit = timeUnit;
    }

    /**
     * 实例化出每到指定时间时执行一次的定时事件
     *
     * @param cronTime 执行时间 例如:HH:mm:ss 、 mm:ss 、 ss
     * @return 距离下个时间点的秒数
     */
    public static Task cron(String cronTime, Runnable event) {
        long[] result = TaskTimeUtil.parseCron(cronTime);
        return new Task(result[0], result[1], TimeUnit.SECONDS, event);
    }

    /**
     * 实例化出每到指定时间时执行一次的定时事件
     *
     * @param timeValue 在什么时间执行(例:值为5的时候,并且时间单位为分，则执行时间为: 10:05、11：05、12：05...)
     * @param timeUnit  时间单位
     */
    public static Task cronDelay(int timeValue, TimeUnit timeUnit, Runnable event) {
        long period;
        switch (timeUnit) {
            case SECONDS:
                period = timeValue;
                break;
            case MINUTES:
                period = timeValue * 60L;
                break;
            case HOURS:
                period = timeValue * 60L * 60L;
                break;
            default:
                throw new RuntimeException("只支持TimeUnit为SECONDS、MINUTES、HOURS的值");
        }
        return new Task(
                TaskTimeUtil.getCronDelaySecond(timeValue, timeUnit)
                , period
                , TimeUnit.SECONDS
                , event
        );
    }

    /**
     * 实例化每满整指定时间后间隔执行的定时事件(例:值为5的时候、并且时间单位为分，则执行时间为：10:00、10：05、10：10、10：15...)
     *
     * @param everyTime 指定的满足的时间
     * @param timeUnit  时间单位
     * @param event     执行事件
     */
    public static Task cronEveryDelay(int everyTime, TimeUnit timeUnit, Runnable event) {
        long period;
        switch (timeUnit) {
            case SECONDS:
                period = everyTime;
                break;
            case MINUTES:
                period = everyTime * 60L;
                break;
            case HOURS:
                period = everyTime * 60L * 60L;
                break;
            default:
                throw new RuntimeException("只支持TimeUnit为SECONDS、MINUTES、HOURS的值");
        }
        return new Task(
                TaskTimeUtil.getCronEveryDelaySecond(everyTime, timeUnit)
                , period
                , TimeUnit.SECONDS
                , event
        );
    }

    public Runnable getEvent() {
        return event;
    }

    public void setEvent(Runnable event) {
        this.event = event;
    }

    public Long getInitialDelay() {
        return initialDelay;
    }

    public void setInitialDelay(Long initialDelay) {
        this.initialDelay = initialDelay;
    }

    public Long getPeriod() {
        return period;
    }

    public void setPeriod(Long period) {
        this.period = period;
    }

    public TimeUnit getTimeUnit() {
        return timeUnit;
    }

    public void setTimeUnit(TimeUnit timeUnit) {
        this.timeUnit = timeUnit;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }
}
